package com.chenfengyao.gamereversi

import androidx.lifecycle.ViewModel
import com.chenfengyao.gamereversi.ai.AIDifficulty

import com.chenfengyao.gamereversi.ai.ComputerPlayer
import com.chenfengyao.gamereversi.ai.LegacyStrategy

import com.chenfengyao.gamereversi.core.ChessPiece
import com.chenfengyao.gamereversi.core.Referee
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow

class MainViewModel : ViewModel() {
    val referee = Referee()

    private val _blackPlayerIdentityFlow = MutableStateFlow(PlayerIdentity.HUMAN)
    val blackPlayerIdentityFlow = _blackPlayerIdentityFlow.asStateFlow()

    private val _blackDifficultyFlow = MutableStateFlow(AIDifficulty.MEDIUM)
    val blackDifficultyFlow = _blackDifficultyFlow.asStateFlow()

    private val _whiteDifficultyFlow = MutableStateFlow(AIDifficulty.MEDIUM)
    val whiteDifficultyFlow = _whiteDifficultyFlow.asStateFlow()

    private val _isThinkingFlow = MutableStateFlow(false)
    val isThinkingFlow = _isThinkingFlow.asStateFlow()

    private val _whitePlayerIdentityFlow = MutableStateFlow(PlayerIdentity.HUMAN)
    val whitePlayerIdentityFlow = _whitePlayerIdentityFlow.asStateFlow()

    private val blackAI = ComputerPlayer().apply { difficulty = _blackDifficultyFlow.value }
    private val whiteAI = ComputerPlayer().apply { difficulty = _whiteDifficultyFlow.value }

    private val _blackUseLegacyFlow = MutableStateFlow(false)
    val blackUseLegacyFlow = _blackUseLegacyFlow.asStateFlow()
    private val _whiteUseLegacyFlow = MutableStateFlow(false)
    val whiteUseLegacyFlow = _whiteUseLegacyFlow.asStateFlow()


    enum class PlayerIdentity {
        HUMAN, AI
    }

    suspend fun useAIPlay(piece: ChessPiece): Pair<Int, Int> {
        _isThinkingFlow.value = true
        return try {
            coroutineScope {
                when (piece) {
                    ChessPiece.BLACK -> {
                        blackAI.difficulty = _blackDifficultyFlow.value
                        if (blackUseLegacyFlow.value) LegacyStrategy.nextMove(referee.board, piece)
                        else blackAI.getNextStep(referee.board, piece)
                    }
                    ChessPiece.WHITE -> {
                        whiteAI.difficulty = _whiteDifficultyFlow.value
                        if (whiteUseLegacyFlow.value) LegacyStrategy.nextMove(referee.board, piece)
                        else whiteAI.getNextStep(referee.board, piece)
                    }
                    else -> -1 to -1
                }
            }
        } finally {
            _isThinkingFlow.value = false
        }
    }

    fun needAIPlay(piece: ChessPiece): Boolean {
        return when (piece) {
            ChessPiece.BLACK -> _blackPlayerIdentityFlow.value == PlayerIdentity.AI
            ChessPiece.WHITE -> _whitePlayerIdentityFlow.value == PlayerIdentity.AI
            else -> false
        }
    }

    /**
     * 切换玩家身份
     */
    fun changePlayerIdentity(piece: ChessPiece) {
        if (piece == ChessPiece.BLACK) {
            _blackPlayerIdentityFlow.value =
                if (_blackPlayerIdentityFlow.value == PlayerIdentity.HUMAN) PlayerIdentity.AI else PlayerIdentity.HUMAN
        } else {
            _whitePlayerIdentityFlow.value =
                if (_whitePlayerIdentityFlow.value == PlayerIdentity.HUMAN) PlayerIdentity.AI else PlayerIdentity.HUMAN
        }
    }

    fun setBlackDifficulty(difficulty: AIDifficulty) {
        _blackDifficultyFlow.value = difficulty
        blackAI.difficulty = difficulty
        _blackUseLegacyFlow.value = false
    }

    fun setWhiteDifficulty(difficulty: AIDifficulty) {
        _whiteDifficultyFlow.value = difficulty
        whiteAI.difficulty = difficulty
        _whiteUseLegacyFlow.value = false
    }

    fun setBlackEngineLegacy(use: Boolean) {
        _blackUseLegacyFlow.value = use
    }

    fun setWhiteEngineLegacy(use: Boolean) {
        _whiteUseLegacyFlow.value = use
    }

}